package com.android.kotlincoroutinemvvmdemo.view
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.SurfaceHolder
import android.view.SurfaceView
import com.android.kotlincoroutinemvvmdemo.R
/*
*  SurfaceView本质也是一个view
*  适用于频繁刷新数据或者刷新数据数据量比较大的场景
*  通过一个子线程进程进行界面的绘制刷新
*  底层采用双缓冲机制
* */
abstract class SurfaceViewTemplate @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null
) : SurfaceView(context, attributeSet), SurfaceHolder.Callback, Runnable {

    val mHolder: SurfaceHolder = holder

    private var canvas: Canvas? = null
    private var mIsDrawing = false

    val minStrokeWidth = context.resources.getDimension(R.dimen.dp_1)

    var mWidth = 0
    var mHeight = 0

    init {
        //mHolder.addCallback(this)
        isFocusable = true
        isFocusableInTouchMode = true
        keepScreenOn = true
    }

    override fun surfaceCreated(holder: SurfaceHolder) {
        mIsDrawing = true
        Thread(this).start()
    }

    override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {}

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        mIsDrawing = false
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        mWidth = when(MeasureSpec.getMode(widthMeasureSpec)) {
            MeasureSpec.EXACTLY -> {
                MeasureSpec.getSize(widthMeasureSpec)
            }
            else -> {
                context.resources.getDimension(R.dimen.dp_60).toInt()
            }
        } - paddingStart - paddingEnd

        mHeight = when(MeasureSpec.getMode(heightMeasureSpec)) {
            MeasureSpec.EXACTLY -> {
                MeasureSpec.getSize(heightMeasureSpec)
            }
            else -> {
                context.resources.getDimension(R.dimen.dp_60).toInt()
            }
        } - paddingTop - paddingBottom

        setMeasuredDimension(mWidth, mHeight)
    }

    override fun run() {
        while (mIsDrawing) {
             draw()
        }
    }

    private fun draw() {
        try {
            canvas = mHolder.lockCanvas()
            canvas?.apply {
                save()
                onDrawContent()
                restore()
            }
        } catch (ex: Exception) {
            ex.printStackTrace()
        } finally {
            if (canvas != null) {
                mHolder.unlockCanvasAndPost(canvas)
            }
        }
    }

    abstract fun Canvas.onDrawContent()
}